package com.espirit.smc.client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.io.IOUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.type.CollectionType;
import org.codehaus.jackson.map.type.SimpleType;

import com.espirit.smc.CompareResult;
import com.espirit.util.PropertiesUtils;

public class ClientMain {

	public static final Set<String> hosts;
	static {
		hosts = new HashSet<String>();
		hosts.add("127.0.0.1");
		hosts.add("localhost");
	}

	public static void main(String[] args) {
		Options options = new Options();
		options.addOption("P", true, "client property path");
		CommandLineParser parser = new BasicParser();
		ClientProperties properties = null;
		try {
			CommandLine cmd = parser.parse(options, args);
			String propertPath = null;
			if (cmd.hasOption('P')) {
				propertPath = (String) cmd.getOptionValue('P');
				System.out.println("属性文件路径:" + propertPath);
			}
			properties = PropertiesUtils.loadClientProperties(propertPath);
		} catch (ParseException e) {
			System.err.println("命令格式错误！请按如下格式执行 java -jar smc-client.jar [-P client.properties]");
		} catch (IOException e) {
			System.err.println("无法读取客户端配置！");
			System.exit(0);
			return;
		}
		if (properties == null) {
			System.err.println("无法读取客户端配置！");
			System.exit(0);
			return;
		}
		Client client = new Client(properties);
		String serverUrl = properties.getServerURL();
		boolean isRemote = false;
		try {
			URL url = new URL(serverUrl);
			String host = url.getHost();
			isRemote = !hosts.contains(host);
		} catch (MalformedURLException e) {
			System.err.println("服务器URL配置错误！");
			System.exit(0);
			return;
		}

		System.out.println("开始准备更新....");
		Path fileListPath;
		try {
			fileListPath = client.makeFileList();
		} catch (Exception e) {
			System.err.println("获取本地文件状态错误！");
			System.exit(0);
			return;
		}
		if (isRemote) {
			System.out.println("正在上传本地文件状态列表....");
			client.uploadFileList(fileListPath);
		}
		System.out.println("正在获取需要更新的文件列表....");
		String fileName = fileListPath.getFileName().toString();
		String fileList = client.loadDifferentList(fileName, isRemote);
		try {
			ObjectMapper mapper = new ObjectMapper();
			List<CompareResult> list = mapper.readValue(fileList, CollectionType.construct(List.class, SimpleType.construct(CompareResult.class)));
			if (list.isEmpty()) {
				System.out.println("本地文件已是最新的！不需要更新！");
				System.exit(0);
				return;
			}
			for (CompareResult r : list) {
				System.out.println(r.toString());
			}
			System.out.println("确定要更新以上文件吗?[yes/no]");
			boolean flag = true;
			InputStreamReader isr = new InputStreamReader(System.in);
			BufferedReader reader = new BufferedReader(isr);
			while (flag) {
				String str = reader.readLine();
				if ("no".equals(str)) {
					System.out.println("正在取消本次更新...");
					flag = false;
					IOUtils.closeQuietly(isr);
					IOUtils.closeQuietly(reader);
					System.out.println("放弃更新!");
					System.exit(0);
					return;
				} else if ("yes".equals(str)) {
					flag = false;
				} else {
					System.err.println("输入错误，请重新输入[yes/no]：");
				}
			}
			IOUtils.closeQuietly(isr);
			IOUtils.closeQuietly(reader);
		} catch (Exception e) {
			System.err.println("读取更新文件列表错误....");
			System.exit(0);
			return;
		}
		Path path = null;
		if (isRemote) {
			System.out.println("正在下载更新包.....");
			path = client.loadUpdatePackage(String.valueOf(fileList));
		}
		try {
			if (isRemote) {
				client.update(path);
			} else {
				client.update(fileList);
			}
		} catch (IOException e) {
			System.err.println("更新失败...." + e.getMessage());
			e.printStackTrace();
		}
		System.out.println("恭喜！更新成功！");
	}

}
